#pragma once
#include <bondlib/BondMarketStream.h>
#include <bondlib/RealTimeDeal/IRealTimeDealModel.h>
#include <bondlib/SSSortInfo.h>

#include <vector>

#include "../Filter/FilterInterface.h"

class MultiBrokerStat;
namespace detail {
class ScreenRecordCache;
class MultiBrokerStat;
class RealTimeDealFilter;
class RealTimeDealSorter;
class RealTimeDealIndexList;
struct ColumnOrder;
void GetColumnOrders(const CSortInfoManager& sortinfo,
                     std::vector<ColumnOrder>& orders);
}  // namespace detail

class IFlasher {
 public:
  virtual void addFlash(std::string id) = 0;
  virtual void removeFlash(std::string id) = 0;
};

class CDealSorter;
class CDealFilter;
class RealTimeDealModel : public IRealTimeDealModel {
 protected:
  typedef detail::ScreenRecordCache ScreenCache;
  typedef detail::RealTimeDealFilter Filter;
  typedef detail::RealTimeDealSorter Sorter;
  typedef detail::MultiBrokerStat MultiChecker;
  typedef detail::RealTimeDealIndexList DealIndexList;
  bool m_bCFETS;
  MultiChecker* m_multi;

  // 保存当前界面中的所有过滤后的成交信息的indexId的容器
  // 每次插入,删除,更新,都会以极快的速度,极低的代价维持
  // 成交记录的有序性,避免旧版每次刷新的重新全部拉取重新排序的高昂开销
  // 此数据结构/基数已经应用到最优报价的主表格中
  DealIndexList* m_keys;

  // 保存每次从底层读取到的一屏幕记录
  // 复制,拷贝,点击等动作,都是基于此结构
  // 将界面与底层个离开,减少复杂性,降低性能开销
  ScreenCache* m_screen_cache;  //

  Sorter* m_sorter;  // 排序器
  CSortInfoManager
      m_sort_info;  // 当前记录的排序信息,决定一条记录如何与另一条记录进行比较

  Filter* m_filter;  // 过滤器

  // 每个batchid,表示一次E_FID_QB_MARKET_STREAM_DEAL_PUSH消息的推送
  // 此字段用于表示成交界面中已经更新到的进度
  // 由于多线程原因,底层数据可能已经更新到前面了,即底层的batchid比此值大
  // 此时仅仅需要更新滞后的批次数据即可
  // 之后的批次数据保存在CDealBatchCache中
  int m_batchid;
  int64_t m_stateid;

  bool m_need_update;

  // 每次更改过滤器的时候,将此值设为false,
  // 每次AddRecord的时候,如果为false,那么将sortinfo传递给m_sorter
  // 此值表示排序信息已经从m_sort_info传递给m_sorter
  bool m_sortinfo_set;
  IFlasher* m_flasher = nullptr;

 public:
  RealTimeDealModel();
  ~RealTimeDealModel();
  void SetCFETSModel(bool bCFETS) { m_bCFETS = bCFETS; };
  bool IsNeedUpdate() const { return m_need_update; }
  int GetMultiCount() const;
  bool GetCacheId(int row, DealIndex& id);
  bool GetCacheRow(const DealIndex& id, int& row);
  bool GetCacheRecord(const DealIndex& id, MarketStreamInfo& record) const;
  virtual int GetRecords(int& pos, int rowCount, MarketStreamInfo* records);
  // 获取CFETS所有数据
  int GetCFETSAllRecords(MarketStreamInfo* records);
  void setFlaser(IFlasher* f) { m_flasher = f; }

 public:  // 继承IRealTimeDealModel,与底层交互的接口
  virtual void ResetKeys();
  virtual int GetCount() const;
  virtual int64 GetState() const;
  virtual void SetState(int64 state);
  virtual int GetBatchId() const { return m_batchid; }
  virtual void SetBatchId(int id) { m_batchid = id; }
  virtual void AddFlash(int batchid, const void* info);
  virtual void AddRecord(int batchid, const void* info);
  virtual void ClearFlash();
  virtual int GetKeys(int pos, int count, void* keys);
  virtual bool IsMultiEnable() const;
  virtual void CheckMulti(const IRecordMap* records);
  virtual void SyncKeys(const IBatchedKeys* keys, const IRecordMap* records);
  virtual void StartCompare(const IRecordMap* records);
  virtual void EndCompare(const IRecordMap* records);

 public:
  detail::RealTimeDealFilter* GetFilter() { return m_filter; }
  CSortInfoManager& GetSortInfo() { return m_sort_info; }
  const CSortInfoManager& GetSortInfo() const { return m_sort_info; }

 public:                            // 6种基础事件
  void OnScroll();                  // 50
  void OnFlash();                   // 200
  void OnPush();                    // 300
  void OnSort();                    // 1000
  void OnFilter(bool multiEnable);  // 1000
 protected:                         // 内部函数
  int GetRecordCount() { return GetCount(); }
  void SortImpl(std::vector<DealIndex>& keys, const IRecordMap* records,
                bool force);
};
